#include "ps2_remote_control.h"


ps2_data_t ps2_data;

u8 Data[9] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //数据存储数组


//向手柄发送命令
static void ps2_send_cmd(u8 cmd)
{
  volatile u16 ref = 0x01;
  Data[1] = 0;
  for (ref = 0x01; ref < 0x0100; ref <<= 1)
  {
    if (ref & cmd)
    {
      PS2_DO(GPIO_PIN_SET);                   //输出以为控制位
    } 
    else
    {
      PS2_DO(GPIO_PIN_RESET);    
    }

    PS2_CK(GPIO_PIN_SET);                        //时钟拉高
    delay_us(10);
    PS2_CK(GPIO_PIN_RESET);
    delay_us(10);
    PS2_CK(GPIO_PIN_SET);
    if (PS2_DATAI)
      Data[1] = ref | Data[1];
  }
}


//读取手柄数据
static void ps2_read_data(void)
{
  volatile u8 byte = 0;
  volatile u16 ref = 0x01;

  PS2_CS(GPIO_PIN_RESET);

  ps2_send_cmd(0x01);  //开始命令
  ps2_send_cmd(0x42);  //请求数据

  for (byte = 2; byte < 9; byte++)          //开始接受数据
  {
    for (ref = 0x01; ref < 0x100; ref <<= 1)
    {
      PS2_CK(GPIO_PIN_SET);
      delay_us(5);
      PS2_CK(GPIO_PIN_RESET);
      delay_us(5);
      PS2_CK(GPIO_PIN_SET);
      if (PS2_DATAI)
        Data[byte] = ref | Data[byte];

    }
    delay_us(16);
  }
  PS2_CS(GPIO_PIN_SET);
}

//清除数据缓冲区
static void PS2_ClearData()
{
  u8 a;
  for (a = 0; a < 9; a++)
    Data[a] = 0x00;
}

//对读出来的PS2的数据进行处理      只处理了按键部分         默认数据是红灯模式  只有一个按键按下时
//按下为0， 未按下为1
void ps2_data_refresh(void)
{
  PS2_ClearData();
  ps2_read_data();
  
  u16 keybit = (Data[4] << 8) | Data[3];     //这是16个按键  按下为0， 未按下为1

  ps2_data.select = !((keybit >> 0) & 1);
  ps2_data.l3 = !((keybit >> 1) & 1);
  ps2_data.r3 = !((keybit >> 2) & 1);
  ps2_data.start = !((keybit >> 3) & 1);
  ps2_data.up = !((keybit >> 4) & 1);
  ps2_data.right = !((keybit >> 5) & 1);
  ps2_data.down = !((keybit >> 6) & 1);
  ps2_data.left = !((keybit >> 7) & 1);
  ps2_data.l2= !((keybit >> 8) & 1);
  ps2_data.r2 = !((keybit >> 9) & 1);
  ps2_data.l1 = !((keybit >> 10) & 1);
  ps2_data.r1 = !((keybit >> 11) & 1);
  ps2_data.green = !((keybit >> 12) & 1);
  ps2_data.red = !((keybit >> 13) & 1);
  ps2_data.blue = !((keybit >> 14) & 1);
  ps2_data.pink = !((keybit >> 15) & 1);

  ps2_data.rx = (Data[5]-128);
  ps2_data.ry = -(Data[6]-128);
  ps2_data.lx = (Data[7]-128);
  ps2_data.ly = -(Data[8]-128);

}


/*********手柄配置初始化*********/
//short poll
static void PS2_ShortPoll(void)
{
  PS2_CS(GPIO_PIN_RESET);
  delay_us(16);
  ps2_send_cmd(0x01);
  ps2_send_cmd(0x42);
  ps2_send_cmd(0x00);
  ps2_send_cmd(0x00);
  ps2_send_cmd(0x00);
  PS2_CS(GPIO_PIN_SET);
  delay_us(16);
}

//进入配置
static void PS2_EnterConfig(void)
{
  PS2_CS(GPIO_PIN_RESET);
  delay_us(16);
  ps2_send_cmd(0x01);
  ps2_send_cmd(0x43);
  ps2_send_cmd(0x00);
  ps2_send_cmd(0x01);
  ps2_send_cmd(0x00);
  ps2_send_cmd(0x00);
  ps2_send_cmd(0x00);
  ps2_send_cmd(0x00);
  ps2_send_cmd(0x00);
  PS2_CS(GPIO_PIN_SET);
  delay_us(16);
}

//发送模式设置
static void PS2_TurnOnAnologMode(void)
{
  PS2_CS(GPIO_PIN_RESET);
  delay_us(16);
  ps2_send_cmd(0x01);
  ps2_send_cmd(0x44);
  ps2_send_cmd(0x00);
  ps2_send_cmd(0x01);    //0x01:anolog    0x00:digital
  ps2_send_cmd(0xEE);    //0x03:锁存设置，不可通过按键“mode"设置模式   0xEE:不锁存设置
  ps2_send_cmd(0x00);
  ps2_send_cmd(0x00);
  ps2_send_cmd(0x00);
  ps2_send_cmd(0x00);
  PS2_CS(GPIO_PIN_SET);
  delay_us(16);
}

//完成并保存设置
static void PS2_ExitConfig(void)
{
  PS2_CS(GPIO_PIN_RESET);
  delay_us(16);
  ps2_send_cmd(0x01);
  ps2_send_cmd(0x43);
  ps2_send_cmd(0x00);
  ps2_send_cmd(0x00);
  ps2_send_cmd(0x5A);
  ps2_send_cmd(0x5A);
  ps2_send_cmd(0x5A);
  ps2_send_cmd(0x5A);
  ps2_send_cmd(0x5A);
  PS2_CS(GPIO_PIN_SET);
  delay_us(16);
}

//手柄配置初始化
void ps2_mode_config(void)
{
  PS2_ShortPoll();
  PS2_ShortPoll();
  PS2_ShortPoll();
  PS2_EnterConfig();
  PS2_TurnOnAnologMode();
  PS2_ExitConfig();
}


//判断是否为红灯模式
//返回值；1，红灯模式
//		  其他，其他模式
bool ps2_is_red_mode(void)
{
  PS2_CS(GPIO_PIN_RESET);
  ps2_send_cmd(0x01);  //开始命令
  ps2_send_cmd(0x42);  //请求数据
  PS2_CS(GPIO_PIN_SET);
  if (Data[1] == 0X73)
    return 1;
  else
    return 0;
}


void ps2_test(void)
{
  while(1)
  {
    printf("mode: %d \n", ps2_is_red_mode());
    ps2_data_refresh();
    
    printf("%d %d %d %d \n", ps2_data.lx, ps2_data.ly, ps2_data.rx, ps2_data.ry);
    
    printf("l1: %d\n", ps2_data.l1);
    
    delay_ms(500);
  }
}


